package com.wq.payunion.oauth2.useroauth2.aop;

import com.fasterxml.jackson.databind.deser.impl.BeanPropertyMap;
import com.wq.payunion.oauth2.useroauth2.exceptions.OAuthException;
import com.wq.payunion.oauth2.useroauth2.model.OAuthResult;
import com.wq.payunion.oauth2.useroauth2.model.common.CommonResult;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @Author: wangqiang20995
 * @Date:2018 年 9 月 16 日 0016
 * @Description:
 * @Resource:
 */
@Component
@Aspect
public class ControllerAspect {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("execution(* com.wq.payunion.oauth2.useroauth2.controller..*(..))")
    public void aspect(){};

    @Around("aspect()")
    public CommonResult buildCommonResult(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        CommonResult commonResult ;
        logger.info("start execute method --> {}",methodName);
        try {
            doPreCheck(joinPoint.getArgs());
            commonResult = (CommonResult) ((ProceedingJoinPoint)joinPoint).proceed();
            doPostCheck(commonResult);
        }catch (Throwable e){
            logger.error(e.getMessage(),e);
            commonResult = new CommonResult();
            if(e instanceof OAuthException){//业务性失败
                commonResult.setRequestStatus(CommonResult.SUCCESS_REQUEST_STATUS);
                commonResult.setRequestMessage(CommonResult.SUCCESS_REQUEST_MESSAGE);
                commonResult.setServiceStatus(CommonResult.FAILED_SERVICE_STATUS);
            }else {
                commonResult.setRequestStatus(CommonResult.FAILED_REQUEST_MESSAGE);
                commonResult.setRequestMessage(CommonResult.FAILED_REQUEST_MESSAGE);
                commonResult.setServiceStatus(CommonResult.FAILED_SERVICE_STATUS);
            }
            commonResult.setServiceMessage(e.getMessage());
        }
        logger.info("end execute method and return --> [{}]",commonResult);
        return commonResult;
    }

    private CommonResult doPostCheck(CommonResult commonResult){
        commonResult.setRequestStatus(CommonResult.SUCCESS_REQUEST_STATUS);
        commonResult.setRequestMessage(CommonResult.SUCCESS_REQUEST_MESSAGE);
        commonResult.setServiceStatus(CommonResult.SUCCESS_SERVICE_STATUS);
        commonResult.setServiceMessage(CommonResult.SUCCESS_SERVICE_MESSAGE);
        OAuthResult authResult = (OAuthResult) commonResult.getServiceResponse("data");

        commonResult.setServiceResponse(transferOauth(authResult,commonResult));
        return commonResult;
    }


    //此时的话commonResult的对象其实是只会被一个线程操作，所以不存在hashMap的并发问题
    private Map<String,Object> transferOauth(OAuthResult oAuthResult,CommonResult commonResult){
        Map<String,Object> map = new HashMap<>();
        map.put("uuid",oAuthResult.getUuid());
        map.put("authStatus",oAuthResult.getAuthStatus());
        if(oAuthResult.isSuccessFlag()){
            commonResult.setServiceStatus(CommonResult.SUCCESS_SERVICE_STATUS);
            commonResult.setServiceMessage(CommonResult.SUCCESS_SERVICE_MESSAGE);
        }else {
            commonResult.setServiceStatus(CommonResult.FAILED_SERVICE_STATUS);
            commonResult.setServiceMessage(oAuthResult.getCallInfo());
        }
        if(oAuthResult.getResponse().size() > 0){
            Iterator<Map.Entry<String,Object>> iterator = oAuthResult.getResponse().entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<String,Object> entry = iterator.next();
                map.put(entry.getKey(),entry.getValue());
            }
        }

        commonResult.removeServiceResultByKey("data");
        return map;
    }
    private void doPreCheck(Object[] args){

    }
}
